/*
 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package javax.naming;

/**
 * This class represents a name-to-object binding found in a context.
 * <p>
 * A context consists of name-to-object bindings.
 * The Binding class represents such a binding.  It consists
 * of a name and an object. The <code>Context.listBindings()</code>
 * method returns an enumeration of Binding.
 * <p>
 * Use subclassing for naming systems that generate contents of
 * a binding dynamically.
 * <p>
 * A Binding instance is not synchronized against concurrent access by multiple
 * threads. Threads that need to access a Binding concurrently should
 * synchronize amongst themselves and provide the necessary locking.
 *
 * @author Rosanna Lee
 * @author Scott Seligman
 * @since 1.3
 */

public class Binding extends NameClassPair {
    /**
     * Contains this binding's object.
     * It is initialized by the constructor and can be updated using
     * <tt>setObject</tt>.
     *
     * @serial
     * @see #getObject
     * @see #setObject
     */
    private Object boundObj;

    /**
     * Constructs an instance of a Binding given its name and object.
     * <p>
     * <tt>getClassName()</tt> will return
     * the class name of <tt>obj</tt> (or null if <tt>obj</tt> is null)
     * unless the class name has been explicitly set using <tt>setClassName()</tt>
     *
     * @param name The non-null name of the object. It is relative
     *             to the <em>target context</em> (which is
     *             named by the first parameter of the <code>listBindings()</code> method)
     * @param obj  The possibly null object bound to name.
     * @see NameClassPair#setClassName
     */
    public Binding(String name, Object obj) {
        super(name, null);
        this.boundObj = obj;
    }

    /**
     * Constructs an instance of a Binding given its name, object, and whether
     * the name is relative.
     * <p>
     * <tt>getClassName()</tt> will return the class name of <tt>obj</tt>
     * (or null if <tt>obj</tt> is null) unless the class name has been
     * explicitly set using <tt>setClassName()</tt>
     *
     * @param name       The non-null string name of the object.
     * @param obj        The possibly null object bound to name.
     * @param isRelative true if <code>name</code> is a name relative
     *                   to the target context (which is named by
     *                   the first parameter of the <code>listBindings()</code> method);
     *                   false if <code>name</code> is a URL string.
     * @see NameClassPair#isRelative
     * @see NameClassPair#setRelative
     * @see NameClassPair#setClassName
     */
    public Binding(String name, Object obj, boolean isRelative) {
        super(name, null, isRelative);
        this.boundObj = obj;
    }

    /**
     * Constructs an instance of a Binding given its name, class name, and object.
     *
     * @param name      The non-null name of the object. It is relative
     *                  to the <em>target context</em> (which is
     *                  named by the first parameter of the <code>listBindings()</code> method)
     * @param className The possibly null class name of the object
     *                  bound to <tt>name</tt>. If null, the class name of <tt>obj</tt> is
     *                  returned by <tt>getClassName()</tt>. If <tt>obj</tt> is also
     *                  null, <tt>getClassName()</tt> will return null.
     * @param obj       The possibly null object bound to name.
     * @see NameClassPair#setClassName
     */
    public Binding(String name, String className, Object obj) {
        super(name, className);
        this.boundObj = obj;
    }

    /**
     * Constructs an instance of a Binding given its
     * name, class name, object, and whether the name is relative.
     *
     * @param name       The non-null string name of the object.
     * @param className  The possibly null class name of the object
     *                   bound to <tt>name</tt>. If null, the class name of <tt>obj</tt> is
     *                   returned by <tt>getClassName()</tt>. If <tt>obj</tt> is also
     *                   null, <tt>getClassName()</tt> will return null.
     * @param obj        The possibly null object bound to name.
     * @param isRelative true if <code>name</code> is a name relative
     *                   to the target context (which is named by
     *                   the first parameter of the <code>listBindings()</code> method);
     *                   false if <code>name</code> is a URL string.
     * @see NameClassPair#isRelative
     * @see NameClassPair#setRelative
     * @see NameClassPair#setClassName
     */
    public Binding(String name, String className, Object obj, boolean isRelative) {
        super(name, className, isRelative);
        this.boundObj = obj;
    }

    /**
     * Retrieves the class name of the object bound to the name of this binding.
     * If the class name has been set explicitly, return it.
     * Otherwise, if this binding contains a non-null object,
     * that object's class name is used. Otherwise, null is returned.
     *
     * @return A possibly null string containing class name of object bound.
     */
    public String getClassName() {
        String cname = super.getClassName();
        if (cname != null) {
            return cname;
        }
        if (boundObj != null)
            return boundObj.getClass().getName();
        else
            return null;
    }

    /**
     * Retrieves the object bound to the name of this binding.
     *
     * @return The object bound; null if this binding does not contain an object.
     * @see #setObject
     */

    public Object getObject() {
        return boundObj;
    }

    /**
     * Sets the object associated with this binding.
     *
     * @param obj The possibly null object to use.
     * @see #getObject
     */
    public void setObject(Object obj) {
        boundObj = obj;
    }

    /**
     * Generates the string representation of this binding.
     * The string representation consists of the string representation
     * of the name/class pair and the string representation of
     * this binding's object, separated by ':'.
     * The contents of this string is useful
     * for debugging and is not meant to be interpreted programmatically.
     *
     * @return The non-null string representation of this binding.
     */

    public String toString() {
        return super.toString() + ":" + getObject();
    }

    /**
     * Use serialVersionUID from JNDI 1.1.1 for interoperability
     */
    private static final long serialVersionUID = 8839217842691845890L;
};
